package hn.sigit.view;

import hn.sigit.logic.general.ResourceBundleHelper;
import hn.sigit.model.hnd.administrative.HND_NaturalPerson;
import hn.sigit.model.ladm.external.ExtParty;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.MethodExpression;
import javax.el.ValueExpression;
import javax.faces.application.Application;
import javax.faces.context.FacesContext;

import org.jboss.seam.annotations.In;

public abstract class MantHelper<EP extends ExtParty> implements Serializable {
	private static final long serialVersionUID = 1L;
	protected final List<EP> blankList = new ArrayList<EP>();

	protected List<EP> personList;
	protected EP selected;
	protected boolean adding;
	protected boolean editing;
	protected boolean selecting;
	protected String searchSelector;
	protected String searchText;
	
	private boolean addingToList;
	private String addToListMethod;
	private String reRenderComponents;
	
	private String returnValueField;
	
	
	@In
	private MantUISettingsHelper mantUISettingsHelper;
	
	@In(create=true)
	protected ResourceBundleHelper resBundle;
	
	
	public abstract List<EP> getPersonList();
	public abstract void setPersonList(List<EP> personList);
	
	public abstract String addNew();
	public abstract String edit(EP ep);
	public abstract String view(EP ep);
	public abstract String delete(EP ep);
	public abstract String select(EP ep);
	public abstract String saveSelected();
	public abstract String quickSearch();
	
	
	public EP getSelected() {
		return selected;
	}
	public void setSelected(EP selected) {
		this.selected = selected;
	}
	
	
	public boolean isAdding() {
		return adding;
	}
	public boolean isEditing() {
		return editing;
	}
	
	public boolean isSelecting() {
		return selecting;
	}
	public void setSelecting(boolean selecting) {
		this.selecting = selecting;
	}
	
	public String getSearchSelector() {
		return searchSelector;
	}
	public void setSearchSelector(String searchSelector) {
		this.searchSelector = searchSelector;
	}
	
	public String getSearchText() {
		return searchText;
	}
	public void setSearchText(String searchText) {
		this.searchText = searchText;
	}
	
	public boolean isAddingToList() {
		return addingToList;
	}
	public void setAddingToList(boolean addingToList) {
		this.addingToList = addingToList;
	}
	
	public String getAddToListMethod() {
		return addToListMethod;
	}
	public void setAddToListMethod(String addToListMethod) {
		this.addToListMethod = addToListMethod;
	}
	
	public String getReRenderComponents() {
		return reRenderComponents;
	}
	public void setReRenderComponents(String reRenderComponents) {
		this.reRenderComponents = reRenderComponents;
	}
	
	public String getReturnValueField() {
		return returnValueField;
	}
	public void setReturnValueField(String returnValueField) {
		this.returnValueField = returnValueField;
	}
	
	public MantUISettingsHelper getMantUISettingsHelper() {
		return mantUISettingsHelper;
	}
	
	protected void doSelection() {
		doSelection(new String[] { returnValueField },
				new Object[] { getSelected() },
				new Class<?>[] { getSelected().getClass() });
	}
	protected void doSelection(String[] fieldNames, Object[] fieldValues, Class<?>[] classes) {
		Application app = FacesContext.getCurrentInstance().getApplication();
		ExpressionFactory exprFactory = app.getExpressionFactory();
		ELContext elCtx = FacesContext.getCurrentInstance().getELContext();
		ValueExpression ve;
		MethodExpression me;
		
		for (int i = 0; i < fieldNames.length; i++) {
			if (fieldNames[i] != null) {
				ve = exprFactory.createValueExpression(elCtx, "#{" + fieldNames[i] + "}", classes[i]);
				ve.setValue(elCtx, fieldValues[i]);
			}
		}
		if (addingToList && addToListMethod != null) {
			//third parameter is set to null meaning that we do not care for the
			//result type... and no expected parameters for fourth parameter,
			//however we can not use null for this argument
			me = exprFactory.createMethodExpression(elCtx, "#{" + addToListMethod + "}", null, new Class[] {});
			me.invoke(elCtx, null);
		}
	}
	
	protected List<EP> wrapSingle(EP ep) {
		List<EP> epList = new ArrayList<EP>();
		if (ep != null)
			epList.add(ep);
		
		return epList;
	}

}
